DHTMLX Documentation

Implementing custom content in header|footer

Level: Intermediate, Complex

Plain HTML inside headers|footers


All header|footer related commands allow you to use HTML instead of the text, so if you want to have some image inside the header you can directly write it as follows:
grid.setHeader("A,<img src='some.gif'/>,C")
grid.attachFooter("A,<strong>B</strong>,C");
The same thing works while loading data from XML, but you need to be sure the data is correctly escaped:
...
<column>&lt;img src='some.gif'&gt;</column>
The usage of "&gt;" and "&lt;" makes the code poorly readable, so instead of them CDATA sections can be used:
...
<column><![CDATA[ <img src='some.gif'> ]]></column>

Adding custom logic to headers|footers

Starting from dhtmlxgrid 1.5 it is possible to add active content in header|footer by using shortcuts.
The following set of shortcuts is built in:

equal to = N
greater than > N
lesser than < N
lesser or equal <= N
greater or equal >= N
range of values N1 .. N2


The shortcuts can be used within the following commands:
grid.setHeader
grid.attachHeader
grid.attachFooter

grid.setHeader("A,#master_checkbox,C");
grid.attachHeader("#text_filter,#rspan,#text_filter");
Or they can be used with related XML tags in case of configuration from XML:
...
<column ... >#text_search</column>
Shortcuts don't work for data part of grid.

While the main purpose of such shortcuts is filtering and collecting statistics, they can be used to place any complex content in grid headers|footers.

To create custom shortcut you should just create a new function with the corresponding name:

grid=new...
grid._in_header_custom_label=function(tag,index,data){ //name contains "_in_header_"+shortcut_name
       tag.innerHTML="works";
}
grid.setHeader("A,#custom_label,C");
...
The function accepts 3 parameters:
The above mentioned snippet will produce grid with the header like this:
A | works | B

A shortcut can be surrounded by any custom content, in the snippet given above it is just ignored. But we can update the snippet in the following manner:
grid=new...
grid._in_header_custom_label=function(tag,index,data){ //name contains "_in_header_"+shortcut_name
       tag.innerHTML=data[0]+"works"+data[1];
}
grid.setHeader("A,#custom_label,C");
...
data - array of two elements;
data[0] - the text displayed before a shortcut in the header;
data[1] - the text displayed after a shortcut in the header.
grid.setHeader("A,it is {#custom_label}!,C"); // => A | it works! | B
//data was equal to  ["it","!"]

a) Clear button in header

grid=new...
grid._in_header_clear_button=function(tag){                  //name contains "_in_header_"+shortcut_name
    tag.innerHTML=data[0]+"<input type='button' value='clear'>";  //HTML view
    var grid = this;                                                   //store reference for further usage
    tag.firstChild.onclick=function(tag,index){              //on button click
        grid.forEachRow(function(id){                         //for each row in grid
            grid.cells(id,index).setValue("");                 //clear cell value for related column
        })
    }
}
grid.setHeader("A,B{#clear_button},C");
...
In the above mentioned snippet we add an input button inside the header (we use data[0] because we need to preserve the existing label), and attach some code to this button, which will set all values in related column as "".
The cool thing here is that you can still use any column header while the button will be just added to a normal content header because "data[0]+" is used in the code.
If "data[0]+" chunk will be removed - the button will replace all the header text.
In a real application it is more reasonable to use a small image instead of a button for such task.

b) Collapsable columns

Here is another code sample of placing a button inside the header. In this sample a click on the button will collapse the column:

grid=new...
grid._in_header_close_button=function(tag,index,data){                     //name contains "_in_header_"+shortcut_name
    tag.innerHTML=data[0]+"<input type='button' value='close'>";     //HTML view
    var grid = this;                                                      //store reference for further usage
    tag.firstChild.onclick=function(tag,index){                 //on button click
        grid.setColumnHidden(index,true);                      //hide related column
    }
}
grid.setHeader("A,B{#close_button},C");
...


As in the previous snippet all the functionality is based on the existing API, no other in-depth coding is required.

c) Custom look|tooltips for header cell

grid=new...
grid._in_header_special=function(tag){     //name contains "_in_header_"+shortcut_name
    tag.style.color="red";                        //set style for existing header
    tag.title="Warning!";                        //set tooltip for header
}
grid.setHeader("A,B{#special},C");
...
All the previous samples set some HTML inside the header, but you can just modify the existing styles instead of setting new content.
In most cases the styles can be set by using setHeader command parameters, but in some cases dynamic approach described in this sample can be useful as well.

d) Editable header


grid=new...
grid._in_header_editable=function(tag){             //name contains "_in_header_"+shortcut_name
    var grid=this;
    tag.ondblclick=function(e){                        //start edit on dbl-click
        var val=tag.innerHTML;                         //get current header text
        tag.innerHTML="<input type='text'><input type='button' value='done'>"
        tag.firstChild.value=val;                        // set text in editor
        tag.childNodes[1].onclick=function(){    //after clicking "done" button
            tag.innerHTML=tag.firstChild.value;  //replace editor with new text
        }
    }
}
grid.setHeader("A,B{#editable},C");
...

It is possible to add some really complex effects in a neat way by using some code. The snippet stated above shows how headers can be made editable (the visual design is not good - but it's just a sample).
The code will attach ondblclick handler to the cell in question, which will switch static text to input.


In all the samples above the modification was applied to some specific instance of the grid, but it is possible to make some code that will apply a modification for the global prototype, so all instances of the grid will support some new shortcut.
In order to do this you should just use the following syntax :

dhtmlXGridObject.prototype._in_header_SOME=function(tag,index){
....
}

Such code can be stored in a separate js file and used when required (thus, by creating some functionality once, you can easily reuse it).